package com.arm.tools;

import com.alibaba.fastjson.JSONObject;
import com.arm.def.FixedData;
import com.arm.module.weChat.UserWechatInfo;
import com.arm.module.weChat.WXJSConfig;
import com.arm.tools.json.JsonHandler;
import com.arm.tools.myRunTime.MyRunTimeExcption;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.NoSuchAlgorithmException;
import java.util.*;


public class WeiXinUtils {
    private static final String str = null;
    private static Logger logger = LoggerFactory.getLogger(WeiXinUtils.class);
    /**
     * 应用授权作用域，snsapi_base （不弹出授权页面，直接跳转，只能获取用户openid），snsapi_userinfo
     * （弹出授权页面，可通过openid拿到昵称、性别、所在地。并且，即使在未关注的情况下，只要用户授权，也能获取其信息）
     */
    public static final String SNSAPI_BASE = "snsapi_base";
    public static final String SNSAPI_USERINFO = "snsapi_userinfo";
    public static final Long EXPIREIN = 7000*1000l;

    public static   Map<String,String> jsTicket =new HashMap<>();


    /**
     * 微信鉴权URL
     *
     * @param url   鉴权URL后返回的URL
     * @param scope 鉴权方式
     * @return
     */
    public static String oauth2(String url, String scope) {
        String urlE = url;
        try {
            urlE = URLEncoder.encode(url, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        String s = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + FixedData.ENTERPRISE_APP_ID + "&redirect_uri=" + urlE
                + "&response_type=code&scope=" + scope + "&state=STATE#wechat_redirect";
        return s;
    }

    /**
     * @return 签名, sign字段不参加签名
     * @生成签名，详见签名生成算法
     */
    public static String MakeSign(String... arry) {

        Arrays.sort(arry);
        StringBuilder sb = new StringBuilder();
        for (String a : arry) {

            if (StringUtils.isNotBlank(a)) {
                sb.append(a);
            }

        }
        // return genStr(sb.toString());

        System.out.println(sb.toString());
        return sb.toString();
    }

    public static String getSort(Map<String, String> map) {

        Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
        StringBuilder stringA = new StringBuilder();
        while (it.hasNext()) {
            Map.Entry<String, String> entry = it.next();
            if (StringUtils.isNotBlank(entry.getValue())) {
                stringA.append(entry.getKey() + "=" + entry.getValue());

                if (it.hasNext()) {
                    stringA.append("&");
                }
            }
        }
        return stringA.toString();
    }

    public static String MakeSign(Map<String, String> map, String key) {
        String stringSignTemp = getSort(map);
        logger.info("stringSignTemp+=========" + stringSignTemp);
        if (StringUtils.isNotBlank(key)) {
            stringSignTemp += "&key=" + key;
        }
        logger.info("stringSignTemp+=========" + stringSignTemp);
        String sign = MD5Tools.MD5(stringSignTemp).trim().toUpperCase();
        logger.info("sign===========>" + sign);
        return sign;
    }
    //String ticket = weChatService.getTicket(appID, JsapiTicket.TYPE_TICKET);
    public static WXJSConfig getWXConfig(String appID, String url, String ticket) throws MyRunTimeExcption {

        if (org.apache.commons.lang.StringUtils.isBlank(appID)) {
            throw new MyRunTimeExcption("appID is null");
        }
        Map<String, String> map = new TreeMap<String, String>();
        String timeStamp = DateUtil.DateToTimestamp(new Date()).toString();
        map.put("timestamp", timeStamp);
        WXJSConfig wxJSConfig = new WXJSConfig();
        wxJSConfig.setAppId(appID);
        wxJSConfig.setTimestamp(timeStamp);
        wxJSConfig.setDebug(true);
        String nonceStr = GenerateID.getUUID().toUpperCase();
        map.put("noncestr", nonceStr);
        wxJSConfig.setNonceStr(nonceStr);

        map.put("url", url);
        map.put("jsapi_ticket", ticket);
        String Str1 = WeiXinUtils.getSort(map);
        logger.info("getWXConfigStr1   ====================" + Str1);
        String signature = null;
        try {
            signature = SHA1.genStr(Str1);
        } catch (NoSuchAlgorithmException e) {
            logger.info("NoSuchAlgorithmException====================>>>>>>>>>>>>>>>>>>>"+e.getMessage());
            e.printStackTrace();
            throw new MyRunTimeExcption(e.getMessage());
        }
        logger.info("getWXConfig signature====================" + signature);
        wxJSConfig.setSignature(signature);
        wxJSConfig.setJsApiList(Str1 + "<p>" + signature);
        return wxJSConfig;
    }

    /**
     * 获取openId
     * @param appId
     * @param code
     * @return
     */
    public static String getOpenId(String appId, String code) {
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + FixedData.ENTERPRISE_APP_ID + "&secret=" + FixedData.APP_APPSECRET + "&code=" + code + "&grant_type=authorization_code";
        String openid = "";
        try {
            String dsd = HttpClientHelper.doGet(url);
            JSONObject jon = JSONObject.parseObject(dsd);
            logger.info("jon==>" + jon.toString());
            openid = (String) jon.get("openid");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return openid;
    }
    /**
     * 获取openId
     * @param appId
     * @param code
     * @return
     */
    public static UserWechatInfo getUserInfoInWechat(String appId, String code) {
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + FixedData.ENTERPRISE_APP_ID + "&secret=" + FixedData.APP_APPSECRET + "&code=" + code + "&grant_type=authorization_code";
        String openid = "";
        String accessToken = "";
        UserWechatInfo userWechatInfo=new UserWechatInfo();
        try {
            String dsd = HttpClientHelper.doGet(url);
            JSONObject jon = JSONObject.parseObject(dsd);
            logger.info("jon==>" + jon.toString());
            openid = (String) jon.get("openid");
            accessToken = (String) jon.get("access_token");
            userWechatInfo=getUserWechatInfo(accessToken,openid);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return userWechatInfo;
    }
    public static UserWechatInfo getUserWechatInfo(String accessToken, String openId) {
        //String url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + accessToken + "&openid=" + openId;
        String url ="https://api.weixin.qq.com/sns/userinfo?access_token="+accessToken+"&openid="+openId+"&lang=zh_CN";

        logger.info("sendUrl is ==>>"+url);
        UserWechatInfo userWechatInfo = new UserWechatInfo();
        try {
            String getUserWechatInfoJson = HttpClientHelper.doGet(url);
            logger.info("getUserWechatInfoJson==>" + getUserWechatInfoJson);
            //  getUserWechatInfoJson = new String(getUserWechatInfoJson.getBytes("ISO-8859-1"), "UTF-8");

            userWechatInfo = (UserWechatInfo) JsonHandler.jsonToObject(getUserWechatInfoJson, UserWechatInfo.class);
            logger.info(userWechatInfo.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }

        return userWechatInfo;

    }
    public static String getAccessToken() {

        String accessTokenKey = "accessTokenKey_" + FixedData.ENTERPRISE_APP_ID;
        String accessToken = null;
        try {


            WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();
            RedisCache redisCache=  wac.getBean(RedisCache.class);
           // accessToken =(String) redisCache.get(accessTokenKey);
            if (org.apache.commons.lang.StringUtils.isBlank(accessToken)) {
                logger.info("accessToken is null in redies 重新获取accessToken======>>>");
                String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + FixedData.ENTERPRISE_APP_ID + "&secret=" + FixedData.APP_APPSECRET;
                String dsd = HttpClientHelper.doGet(url);
                logger.info("accessToken====>>>" + dsd);
                JSONObject jon = JSONObject.parseObject(dsd);

                accessToken = (String) jon.get("access_token");
                if (org.apache.commons.lang.StringUtils.isBlank(accessToken)) {
                    throw new RuntimeException("获取accessToken失败！accessToken is null");
                }
                logger.info("accessToken==is=???>>" + accessToken);
              //  redisCache.put(accessTokenKey,accessToken,EXPIRE);
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.info("获取accessToken失败=======》》》》》");
        }

        logger.info("accessToken======>>>" + accessToken);
        return accessToken;
    }
    public static String getTicket() {
        //String  ticketKey = "ticketKey_"+FixedData.ENTERPRISE_APP_ID;
        String ticket = WeiXinUtils.jsTicket.get("ticket");
        String timestamp = WeiXinUtils.jsTicket.get("timestamp");
        Long nowTimestamp = new Date().getTime();
        Long subTimestamp = null;
        try {
            try {
                if (org.apache.commons.lang.StringUtils.isNotBlank(timestamp)) {
                    Long ticketTimestamp = Long.parseLong(timestamp);
                    if (ticketTimestamp != null) {
                        subTimestamp = nowTimestamp - ticketTimestamp;
                        logger.info("subTimestamp===>>" + subTimestamp);
                    }

                }
            } catch (NumberFormatException e) {
                logger.info("timestamp 转换出错==》》" + timestamp);
                e.printStackTrace();
            }


            /*  ticket =(String) redisCache.get(ticketKey);*/
            if (org.apache.commons.lang.StringUtils.isBlank(ticket) || (org.apache.commons.lang.StringUtils.isNotBlank(ticket) && org.apache.commons.lang.StringUtils.isBlank(timestamp))
                    || (org.apache.commons.lang.StringUtils.isNotBlank(ticket) && subTimestamp != null && subTimestamp > WeiXinUtils.EXPIREIN)
                    ) {
                logger.info("ticket is null in redies 重新获取ticket======>>>" + ticket + "[" + timestamp + "]");
                String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + getAccessToken() + "&type=jsapi";
                String dsd = HttpClientHelper.doGet(url);
                logger.info("dsd====>>>" + dsd);
                JSONObject jon = JSONObject.parseObject(dsd);

                ticket = (String) jon.get("ticket");
                if (org.apache.commons.lang.StringUtils.isBlank(ticket)) {
                    throw new RuntimeException("获取ticket失败！ticket is null");
                }
                logger.info("ticket==is=???>>" + ticket);
                WeiXinUtils.jsTicket.put("ticket", ticket);
                WeiXinUtils.jsTicket.put("timestamp", String.valueOf(nowTimestamp));
                /* redisCache.put(ticketKey,ticket,EXPIRE);*/
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.info("获取ticket失败=======》》》》》" + e.getMessage());


        }

        logger.info("ticket======>>>" + ticket);
        return ticket;
    }


}
